<?php

/*
class AbstractRouter, container routing requests to other components
based on user defined conditions
Copyright (C) 2012  Petr Čermák

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

require_once 'View.php';
require_once 'Checker.php';
require_once 'Container.php';

abstract class AbstractRouter extends Container{

    protected $defaultPage = null;
    protected $currentComponent = null;

    public function getCurrentComponent(){return $this->currentComponent;}

    /**This function is called before the components are rendered.*/
    protected function beforeRender(){}

    protected abstract function getActivePage();

    public function processRequest(){
        $this->processHelpers();
        $this->beforeRender();
        $view = $this->getView();
        if($view != null)
            $view->setValue("content", $this->createContent());
        else $this->includeContent();
        $this->processAndView();
        //parent::processRequest();
    }

    public function createOutput(){
        ob_start();
        $this->processRequest();
        $content = ob_get_contents();
        ob_end_clean();
        return $content;
    }

    public function setDefaultPage($defaultPage){
        Checker::checkString($defaultPage);
        $this->defaultPage = $defaultPage;
    }

    public function getUsedParameters(){
        return $this->getDeletableParameters() + parent::getUsedParameters();
    }

    protected function getDeletableParameters(){
        if($this->currentComponent == null ||
           $this->currentComponent instanceof View ||
           $this->currentComponent->isPreservationEnabled())
            return array();
        else return $this->currentComponent->getUsedParameters();
    }

    private function renderPage($page){
        $this->checkPage($page);
        $component = $this->getComponent($page);
        if($component != null && $component->isEnabled()){
            $this->currentComponent = $component;
            //$component->initialize();
            $component->processRequest();
        }
    }

    private function createContent(){
        ob_start();
        $this->includeContent();
        $content = ob_get_contents();
        ob_end_clean();
        return $content;
    }

    private function includeContent(){
        $page = $this->getActivePage();
        if($page != null){
            if(is_string($page) && trim($page) != "" && $this->hasComponent($page))
                $this->renderPage($page);
            else if($this->defaultPage != null)
                $this->renderPage($this->defaultPage);
        }
        else if($this->defaultPage != null)
            $this->renderPage($this->defaultPage);
    }

    private function updateComponent($page){
        $this->currentComponent = $this->getComponent($page);
        //$this->lastComponent->initialize();
        if($this->currentComponent instanceof Router)
            $this->currentComponent->updateCurrentComponent();
    }

    public function updateCurrentComponent(){
        $page = $this->getActivePage();
        if($page != null){
            if(is_string($page) && trim($page) != "" && $this->hasComponent($page))
               $this->updateComponent($page);
            else if($this->defaultPage != null)
                $this->updateComponent($this->defaultPage);
        }
        else if($this->defaultPage != null)
            $this->updateComponent($this->defaultPage);
    }

    // --- error checking

    private function checkPage($page){
        if(Checker::isEnabled() && (!is_string($page) || trim($page) == "" || !$this->hasComponent($page)))
            throw new InvalidArgumentException("invalid page name", null, null);
    }

}
?>